package com.pmt.feedplayer.data

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.withContext
import Foundation.*
import UIKit.*
import kotlin.collections.mutableListOf
import Photos.*
import AVFoundation.*
import Darwin.*

/**
 * iOS平台的本地视频扫描器实现
 * 用于扫描iOS设备上的视频文件并返回VideoItem列表
 */
actual class LocalVideoScanner() {
    
    /**
     * 扫描本地视频文件
     * @param offset 偏移量，跳过前面的视频数量
     * @param limit 返回的最大视频数量
     * @return 视频列表
     */
    actual suspend fun scanLocalVideos(offset: Int, limit: Int): List<VideoItem> = withContext(Dispatchers.Default) {
        val videos = mutableListOf<VideoItem>()
        val videoInfoList = mutableListOf<Triple<PHAsset, String, String>>() // (asset, id, fileName)
        
        try {
            // 获取相册授权状态
            val status = PHPhotoLibrary.authorizationStatus()
            
            if (status == PHAuthorizationStatus.NotDetermined) {
                // 请求授权
                PHPhotoLibrary.requestAuthorization { authStatus ->
                    if (authStatus == PHAuthorizationStatus.Authorized) {
                        // 授权成功后，这里不会立即执行，需要在UI线程中重新调用
                    }
                }
                // 暂时返回空列表
                return@withContext videos
            } else if (status != PHAuthorizationStatus.Authorized) {
                // 没有授权
                return@withContext videos
            }
            
            // 创建获取视频的请求
            val fetchOptions = PHFetchOptions()
            val sortDescriptor = NSSortDescriptor(
                key = "creationDate", 
                ascending = false
            )
            fetchOptions.sortDescriptors = listOf(sortDescriptor)
            
            // 获取所有视频
            val fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Video, fetchOptions)
            
            // 计算实际开始和结束索引
            val startIndex = offset.coerceAtLeast(0)
            val endIndex = (startIndex + limit).coerceAtMost(fetchResult.count.toInt() - 1)
            
            // 如果没有视频或偏移量过大，直接返回
            if (fetchResult.count == 0L || startIndex >= fetchResult.count.toInt()) {
                return@withContext videos
            }
            
            // 使用信号量等待异步操作完成
            val semaphore = dispatch_semaphore_create(0)
            var processedCount = 0
            
            // 遍历视频资产，从offset开始，最多获取limit个
            for (i in startIndex..endIndex) {
                val asset = fetchResult.objectAtIndex(i.toULong()) as PHAsset
                
                // 请求视频URL
                val options = PHVideoRequestOptions()
                options.deliveryMode = PHVideoRequestOptionsDeliveryMode.HighQualityFormat
                
                PHImageManager.defaultManager().requestAVAssetForVideo(
                    asset = asset,
                    options = options,
                    resultHandler = { avAsset, audioMix, info ->
                        try {
                            if (avAsset is AVURLAsset) {
                                val videoURL = avAsset.URL.absoluteString()
                                val fileName = avAsset.URL.lastPathComponent() ?: "Video $i"
                                val id = asset.localIdentifier ?: "$i"
                                
                                // 创建临时VideoItem，thumbnailUrl稍后填充
                                val videoItem = VideoItem(
                                    id = id,
                                    videoUrl = videoURL,
                                    thumbnailUrl = "", // 稍后异步填充
                                    title = fileName,
                                    duration = asset.duration.toLong() * 1000, // 转换为毫秒
                                    authorName = "本地文件",
                                    likeCount = 0,
                                    viewCount = 0
                                )
                                
                                synchronized(videos) {
                                    videos.add(videoItem)
                                }
                                
                                synchronized(videoInfoList) {
                                    videoInfoList.add(Triple(asset, id, fileName))
                                }
                            }
                        } catch (e: Exception) {
                            println("Error processing video asset: $e")
                        } finally {
                            // 更新处理计数
                            synchronized(this@LocalVideoScanner) {
                                processedCount++
                                if (processedCount == (endIndex - startIndex + 1)) {
                                    dispatch_semaphore_signal(semaphore)
                                }
                            }
                        }
                    }
                )
            }
            
            // 等待所有视频URL处理完成
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
            
            // 异步生成缩略图，提高性能
            val thumbnailResults = withContext(Dispatchers.Default) {
                val deferredThumbnails = videoInfoList.mapIndexed { index, (asset, id, _) ->
                    async {
                        // 检查缓存中是否已有缩略图
                        val thumbnailPath = getThumbnailPathFromCache(id)
                        if (thumbnailPath.isNotEmpty()) {
                            // 缓存命中，直接使用
                            Pair(index, thumbnailPath)
                        } else {
                            // 生成新缩略图并缓存
                            Pair(index, generateAndCacheVideoThumbnail(asset, id))
                        }
                    }
                }
                
                // 等待所有缩略图生成完成
                awaitAll(*deferredThumbnails.toTypedArray())
            }
            
            // 更新视频项的缩略图路径
            thumbnailResults.forEach { (index, thumbnailPath) ->
                if (index < videos.size) {
                    videos[index] = videos[index].copy(thumbnailUrl = thumbnailPath)
                }
            }
            
        } catch (e: Exception) {
            println("Error scanning videos: $e")
        }
        
        return@withContext videos
    }
    
    /**
     * 从缓存获取缩略图路径
     * @param videoId 视频ID
     * @return 缩略图文件路径，如果不存在返回空字符串
     */
    private fun getThumbnailPathFromCache(videoId: String): String {
        // 获取缓存目录
        val cacheDir = NSSearchPathForDirectoriesInDomains(
            NSSearchPathDirectory.NSCachesDirectory,
            NSSearchPathDomainMask.NSUserDomainMask,
            true
        ).firstOrNull() as? String ?: return ""
        
        val thumbnailDir = "$cacheDir/video_thumbnails"
        val thumbnailFile = "$thumbnailDir/thumb_$videoId.jpg"
        
        return if (NSFileManager.defaultManager().fileExistsAtPath(thumbnailFile)) {
            thumbnailFile
        } else {
            ""
        }
    }
    
    /**
     * 生成并缓存视频缩略图
     * @param asset 视频资产
     * @param videoId 视频ID
     * @return 缩略图文件路径
     */
    private fun generateAndCacheVideoThumbnail(asset: PHAsset, videoId: String): String {
        try {
            // 创建信号量等待缩略图生成
            val semaphore = dispatch_semaphore_create(0)
            var thumbnailPath = ""
            
            // 配置缩略图请求选项
            val options = PHImageRequestOptions()
            options.deliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat
            options.synchronous = false
            
            // 请求缩略图
            PHImageManager.defaultManager().requestImageForAsset(
                asset = asset,
                targetSize = CGSizeMake(320.0, 180.0), // 设置缩略图尺寸
                contentMode = PHImageContentMode.AspectFill,
                options = options
            ) { image: UIImage?, info: Map<Any?, *>? ->
                try {
                    if (image != null) {
                        // 获取缓存目录
                        val cacheDir = NSSearchPathForDirectoriesInDomains(
                            NSSearchPathDirectory.NSCachesDirectory,
                            NSSearchPathDomainMask.NSUserDomainMask,
                            true
                        ).firstOrNull() as? String ?: run {
                            dispatch_semaphore_signal(semaphore)
                            return@requestImageForAsset
                        }
                        
                        // 创建缩略图目录
                        val thumbnailDir = "$cacheDir/video_thumbnails"
                        val fileManager = NSFileManager.defaultManager()
                        
                        if (!fileManager.fileExistsAtPath(thumbnailDir)) {
                            fileManager.createDirectoryAtPath(
                                thumbnailDir,
                                withIntermediateDirectories = true,
                                attributes = null,
                                error = null
                            )
                        }
                        
                        // 创建缩略图文件路径
                        thumbnailPath = "$thumbnailDir/thumb_$videoId.jpg"
                        
                        // 保存图像到文件，使用中等质量以平衡性能和显示效果
                        val imageData = UIImageJPEGRepresentation(image, 0.6) // 60% 质量
                        imageData?.writeToFile(thumbnailPath, atomically = true)
                    }
                } catch (e: Exception) {
                    println("Error saving thumbnail: $e")
                } finally {
                    dispatch_semaphore_signal(semaphore)
                }
            }
            
            // 等待缩略图生成完成
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
            
            return thumbnailPath
        } catch (e: Exception) {
            println("Error generating thumbnail: $e")
            return ""
        }
    }
}